<?php
ArrowController::importModel("controls::mediators.IArrowMediator");
ArrowController::importModel("org.arrowplatform.controls.forms.ArrowFormCtrlManager");

class ArrowFormMediator implements IArrowMediator{
	
	/**
	 * Curr procesed form
	 *
	 * @var Form
	 */
	private $formToCheck;
	
	private $fieldsWithErrors = array();
	private $alerts = array();
	
	/**
	 * Enter description here...
	 *
	 * @var ArrowFormMediator
	 */
	private static $oInstance = null;
	
	/**
	 * Mediator interface implemetaction
	 *
	 * @return ArrowFormMediator
	 */
	public static function getDefault(){
		if( self::$oInstance == null ){
			self::$oInstance = new ArrowFormMediator();
		}
		return self::$oInstance;
	}
	
	private function __construct(){
		$request = ArrowRequestContext::getDefault();
		$this->formToCheck  = ArrowForm::loadForm($request[ArrowForm::FORM_CONTROL_VAR], false);
		
	}
	
	/**
	 * Mediator interface implementaction
	 *
	 * @param RequestContext $request
	 * @return boolean
	 */
	public function getCheckResult( ArrowRequestContext $request ){
		
		$validator = ArrowController::getModelInstance($this->formToCheck->getValidator());
		
		if( !($validator instanceof IArrowFormValidator ) )
			throw new ArrowFormException( "Validator doesn't implement IArrowFormValidator" );
		
		$proposedValues = array();
		
		foreach( $this->formToCheck->getFields() as $field ){
			$value = $this->getRequestValue( $field, $request );
			$proposedValues[$field->getName()] = $value;
		}
		
		$pass = true;
		
		$standardValidateResult = $validator->validate($this->formToCheck, $proposedValues);
		
		$validateDelegate = $this->formToCheck->getProperty("validateDelegate");
		if($validateDelegate){
			$template = ArrowController::$activeProject->getTemplatesStructure()->getTemplateById($this->formToCheck->getTemplateId());
			$pass = call_user_func( array($template->getPageClass(), $validateDelegate), $this->formToCheck, $validator, $proposedValues );
		}
		
		$rq = ArrowRequestContext::getDefault();
		if( $standardValidateResult && $rq["arrowValidateOnly"] != "1" && $pass)
			return true;
			
		$callType = ArrowRouter::getDefault()->getCallType();
		if( $callType == ArrowRouter::ACTION_BEAN_CALL){
			ArrowForm::setDataTransfer( $request[ArrowForm::FORM_CONTROL_VAR], $validator->getFieldsWithErrors(), $proposedValues, $validator->getAlerts() );
		}else if( $callType == ArrowRouter::REMOTE_CALL){
			$this->fieldsWithErrors = $validator->getFieldsWithErrors();
			$this->alerts = $validator->getAlerts();
		}
		
		return false;
	}

	private function getRequestValue(ArrowFormField $field, ArrowRequestContext $request){
		$namespace = $field->getNamespace();
		if( $namespace == false )
			return $request->getRequest( $field->getName() );
		
		$formData = $request->getRequest( $namespace );
		return isset($formData[$field->getName()])?$formData[$field->getName()]:false;
	}
	
	/**
	 * From IArrowMediator interface
	 */
	public function getActionBean(){
		$action = $this->formToCheck->getProperty("actionBean");
		if($action)
			return ArrowController::$activeProject->getBeansStructure()->getBeanByMappingPath( $action );
		return false;
	}

	/**
	 * From IArrowMediator interface
	 */
	public function getAfterTemplate(){
		$template = $this->formToCheck->getProperty("template");
		if($template)
			return ArrowController::$activeProject->getTemplatesStructure()->getTemplateByMappingPath( $template );
		return false;
	}

	/**
	 * From IArrowMediator interface
	 */
	public function getAfterAddress(){
		$address = $this->formToCheck->getProperty("address");
		if($address){
			$address = str_replace("_current_", $_SERVER["REQUEST_URI"], $address);
			$address = str_replace("_referer_", $_SERVER["HTTP_REFERER"], $address);
			
			return $address;
		}
		return false;
	}	
	
	/**
	 * From IArrowMediator interface
	 */
	public function getErrorAsText(){
		$com = "<ul>";
		foreach( $this->fieldsWithErrors as $fieldName => $tmp ){
			$field = $this->formToCheck->getFieldByName($fieldName);
			$alert = $field->getAlert();
			if(empty($alert)) $alert = "Validation of ".$fieldName." not passed.";
			$com.= "<li>". $alert ."</li>";	
		}
		foreach( $this->alerts as $alert ){
			$com.= "<li>". $alert ."</li>";
		}
		$com.= "</ul>";
		
		return $com;
	}
	
	public function getErrorAsTable() {
		$ret = array( "errors" => array(), "alerts" => array() ) ;
		
		foreach( $this->fieldsWithErrors as $fieldName => $alert ){
			$field = $this->formToCheck->getFieldByName($fieldName);
		
			if(empty($alert)) $alert[] = "Validation of ".$fieldName." not passed.";
			$ret["errors"][ $fieldName ] = array(  "alert" => $alert, "namespace" => $field->getNamespace());
		}
		foreach( $this->alerts as $alert ){
			$ret["alerts"][] = $alert;
		}
		
		return $ret;
	}
	
	public function getError() {
		$req = ArrowRequestContext::getDefault();
		if( !isset( $req["arrowmet"] ) ||  $req["arrowmet"] == IArrowMediator::AS_TEXT ) {
			return $this->getErrorAsText();
		} else if( $req["arrowmet"] == IArrowMediator::AS_ARRAY ) {
			return $this->getErrorAsTable();
		}
	}
	
}
?>
